import { isScalar as i, isCollection as h } from '../nodes/identity.js';
import { visit as u } from '../visit.js';
function m(r) {
  if (/[\x00-\x19\s,[\]{}]/.test(r)) {
    const n = `Anchor must not contain whitespace or control characters: ${JSON.stringify(
      r,
    )}`;
    throw new Error(n);
  }
  return !0;
}
function f(r) {
  const t = /* @__PURE__ */ new Set();
  return (
    u(r, {
      Value(n, e) {
        e.anchor && t.add(e.anchor);
      },
    }),
    t
  );
}
function l(r, t) {
  for (let n = 1; ; ++n) {
    const e = `${r}${n}`;
    if (!t.has(e)) return e;
  }
}
function w(r, t) {
  const n = [],
    e = /* @__PURE__ */ new Map();
  let c = null;
  return {
    onAnchor: s => {
      n.push(s), c || (c = f(r));
      const o = l(t, c);
      return c.add(o), o;
    },
    /**
     * With circular references, the source node is only resolved after all
     * of its child nodes are. This is why anchors are set only after all of
     * the nodes have been created.
     */
    setAnchors: () => {
      for (const s of n) {
        const o = e.get(s);
        if (typeof o == 'object' && o.anchor && (i(o.node) || h(o.node)))
          o.node.anchor = o.anchor;
        else {
          const a = new Error(
            'Failed to resolve repeated object (this should not happen)',
          );
          throw ((a.source = s), a);
        }
      }
    },
    sourceObjects: e,
  };
}
export {
  m as anchorIsValid,
  f as anchorNames,
  w as createNodeAnchors,
  l as findNewAnchor,
};
